package com.jcompressor.faces;

import javax.faces.FactoryFinder;
import javax.faces.context.FacesContext;
import javax.faces.context.FacesContextFactory;
import javax.faces.lifecycle.Lifecycle;
import javax.faces.lifecycle.LifecycleFactory;
import javax.servlet.ServletContext;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;

public class FacesContextBuilder {
	
	public FacesContext getFacesContext(final ServletRequest request, final ServletResponse response) {
		FacesContext facesContext = FacesContext.getCurrentInstance();
		if (facesContext != null) {
			return facesContext;
		}
		
		final FacesContextFactory facesContextFactory = (FacesContextFactory)FactoryFinder.getFactory(FactoryFinder.FACES_CONTEXT_FACTORY);
		final LifecycleFactory lifecycleFactory = (LifecycleFactory)FactoryFinder.getFactory(FactoryFinder.LIFECYCLE_FACTORY);
		final Lifecycle lifecycle = lifecycleFactory.getLifecycle(LifecycleFactory.DEFAULT_LIFECYCLE);
		
		final ServletContext servletContext = ((HttpServletRequest)request).getSession().getServletContext();
		facesContext = facesContextFactory.getFacesContext(servletContext, request, response, lifecycle);
		InnerFacesContext.setFacesContextAsCurrentInstance(facesContext);
		
		if (facesContext.getViewRoot() == null) {
			facesContext.setViewRoot(facesContext.getApplication().getViewHandler().createView(facesContext, null));
		}
		
		return facesContext;
	}
	
	public void removeFacesContext() {
		InnerFacesContext.setFacesContextAsCurrentInstance(null);
	}
	
	private abstract static class InnerFacesContext extends FacesContext {
		protected static void setFacesContextAsCurrentInstance(final FacesContext facesContext) {
			FacesContext.setCurrentInstance(facesContext);
		}
	}
	
}